using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GameAOT;
using IQIGame.USDK;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class UILogin : UIBaseWindow
    {
        /// <summary>
        /// 静态配置
        /// </summary>
        private static UICreateConfig _createConfig = new()
        {
            prefabName = nameof(UILogin),
            layer = EUILayer.Main,
        };

        /// <summary>
        /// 创建UI的配置
        /// </summary>
        public override IUICreateConfig createConfig => _createConfig;

        #region Template Generate,don't modify
        protected partial class UIB_UILogin
        {
            #region ObjectBinding Generate
            public UnityEngine.GameObject loginInput { protected set; get; }
            public UnityEngine.GameObject serverList { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btn_Login { protected set; get; }
            public IQIGame.Onigao.Framework.ExInputField input_Username { protected set; get; }
            public IQIGame.Onigao.Framework.ExInputField input_Password { protected set; get; }
            public UnityEngine.GameObject serverNode { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btn_Connect { protected set; get; }
            public UnityEngine.RectTransform img_SelectServer { protected set; get; }
            public UnityEngine.GameObject debugBlock { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<UnityEngine.GameObject>("loginInput", out var __tbv0);
                this.loginInput = __tbv0;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("serverList", out var __tbv1);
                this.serverList = __tbv1;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btn_Login", out var __tbv2);
                this.btn_Login = __tbv2;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExInputField>("input_Username", out var __tbv3);
                this.input_Username = __tbv3;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExInputField>("input_Password", out var __tbv4);
                this.input_Password = __tbv4;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("serverNode", out var __tbv5);
                this.serverNode = __tbv5;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btn_Connect", out var __tbv6);
                this.btn_Connect = __tbv6;
                __binding.TryGetVariableValue<UnityEngine.RectTransform>("img_SelectServer", out var __tbv7);
                this.img_SelectServer = __tbv7;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("debugBlock", out var __tbv8);
                this.debugBlock = __tbv8;
            }
            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify

        /// <summary>
        /// 可以自定义修改的
        /// </summary>
        protected partial class UIB_UILogin
        {
            public virtual void StartBinding(GameObject __go)
            {
                var binding = __go.GetComponent<ObjectBinding>();
                if (binding != null)
                {
                    this.InitBinding(binding);
                }
            }
        }
        protected UIB_UILogin ui { get; set; }
        private UIMsgDispatcher currMsgDispatcher => this._msgDispatcher as UIMsgDispatcher;

        protected override void BeforeInit()
        {
            ui = new UIB_UILogin();
            ui.StartBinding(gameObject);
        }

        PlayerPreferenceString gameUserName = null;
        PlayerPreferenceString gamePassword = null;

        private UIN_OutDebugBlock outDebugBlock;
        private UIItemPool<UINServerNode> _poolServerNode;
        private Action<UINServerNode> _onSelectServerChanged;
        private LoginResponseServerInfo selectServer;
        private bool isUseSdk = false;

        protected override void OnInit()
        {
            DevelopSettingModule.Instance.Initialize();

            this.isUseSdk = ManagerCenter.ProjectSetting.IsSDKMode();
            this._poolServerNode = this.InitPool<UINServerNode>(this.ui.serverNode);
            this.outDebugBlock = this.InitChildNode<UIN_OutDebugBlock>(this.ui.debugBlock);

            this.InitLoginState();

            // 用成员变量初始化一次，防止创建多次Action，导致GC
            this._onSelectServerChanged = OnSelectServerChanged;

            this.ui.btn_Login.AddClickEvent(OnBtnLogin);
            this.ui.btn_Connect.AddClickEvent(OnBtnConnectGame);
            this.outDebugBlock.Show();
        }

        protected override void OnShow(UIBaseData data)
        {

        }

        protected override void OnHide()
        {

        }

        protected override void AddMsgListeners()
        {
            if (this.isUseSdk)
            {
                currMsgDispatcher.AddListener<UserInfo>(MsgEventType.SDK_LOGIN_SUCCESS, this.OnSDKLoginSuccess);
            }
        }

        public UILogin InitLoginState()
        {
            this.ui.loginInput.SetActive(!isUseSdk);
            this.ui.serverList.SetActive(false);

            if (!isUseSdk)
            {
                gameUserName = new PlayerPreferenceString(PlayerPrefsConst.LoginUserName, string.Empty);
                gamePassword = new PlayerPreferenceString(PlayerPrefsConst.LoginPassword, string.Empty);
                this.ui.input_Username.text = gameUserName;
                this.ui.input_Password.text = gamePassword;
            }

            return this;
        }

        public UILogin InitSelectServerList(List<LoginResponseServerInfo> serverDataLists, string lastLoginServerId)
        {
            this.ui.loginInput.SetActive(false);
            this.ui.serverList.SetActive(true);
            bool isHasLast = !string.IsNullOrEmpty(lastLoginServerId);
            // 填充服务器列表
            _poolServerNode.HideAll();
            UINServerNode lastLoginNode = null;
            foreach (var serverData in serverDataLists)
            {
                var node = _poolServerNode.GetOne();
                node.InitServerInfo(serverData, this._onSelectServerChanged);
                if (isHasLast && serverData.serverId.Equals(lastLoginServerId))
                    lastLoginNode = node;
            }
            if (lastLoginNode == null)
                this._poolServerNode.TryGetFirst(out lastLoginNode);// 默认选中第一个
            OnSelectServerChanged(lastLoginNode);
            return this;
        }

        private void OnBtnLogin()
        {
            string _uname = this.ui.input_Username.text;
            string _pwd = this.ui.input_Password.text;
            if (string.IsNullOrEmpty(_uname) || string.IsNullOrEmpty(_pwd))
            {
                return;
            }
            if (!isUseSdk)
            {
                gameUserName.Value = _uname;
                gamePassword.Value = _pwd;
            }

            // 获取账号密码
            LoginRequestBuiltinUserLoginData loginData = new()
            {
                uName = _uname,
                pwd = _pwd
            };
            DoLoginUserAsync(loginData).Forget();
        }

        private void OnSelectServerChanged(UINServerNode selectNode)
        {
            this.ui.img_SelectServer.SetParent(selectNode.transform);
            this.ui.img_SelectServer.anchoredPosition = Vector2.zero;
            this.ui.img_SelectServer.SetAsFirstSibling();
            this.selectServer = selectNode.serverInfo;
        }

        private void OnBtnConnectGame()
        {
            if (this.mUserLoginResponse == null)
            {
                LogGame.Log($"[{nameof(UILogin)}]no user!");
                return;
            }
            if (this.selectServer == null)
            {
                LogGame.Log($"[{nameof(UILogin)}]no server selected!");
                return;
            }
            LoginModule.Instance.LoginGameAsync(this.selectServer, this.mUserLoginResponse).Forget();
        }

        protected override void OnDispose()
        {
            this.mUserLoginResponse = null;
        }

        private LoginResponseUserLogin mUserLoginResponse = null;

        public async UniTaskVoid DoLoginUserAsync(LoginRequestBaseData loginRequestBaseData)
        {
            this.mUserLoginResponse = null;
            var loginResponse = await LoginModule.Instance.LoginUserAsync(loginRequestBaseData);
            if (loginResponse == null)
            {
                NoticeModule.ShowNoticeNoCall(NoticeConstant.ID_NET_ERROR_ON_LOGIN);
                return;
            }
            if (loginResponse.code != 0)
            {
                NoticeModule.ShowErrorNotice(loginResponse.code);
                return;
            }
            this.mUserLoginResponse = loginResponse;
            this.InitSelectServerList(this.mUserLoginResponse.data.districts, this.mUserLoginResponse.data.lastLoginServerId);
        }

        private void OnSDKLoginSuccess(UserInfo userInfo)
        {
            LoginRequestSDKUserLoginData loginData = new()
            {
                channelUid = userInfo.channelUid,
                channelId = userInfo.channelId,
                token = userInfo.token,
            };
            this.DoLoginUserAsync(loginData).Forget();
        }
    }
}
